package com.iking.toolkit.formatdeal.async;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import com.iking.toolkit.formatdeal.dao.FileFormatConversionMapper;
import com.iking.toolkit.formatdeal.enums.FileFormatPathEnum;
import com.iking.toolkit.formatdeal.model.FileFormatConversion;
import com.iking.toolkit.model.Msg;
import com.iking.toolkit.util.*;
import com.iking.toolkit.util.minio.MinioStorage;
import com.iking.toolkit.util.ofd.utils.OfdPdfUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;

/**
 * 功能描述:文件格式转换异步处理
 *
 * @author: yfl
 * @date: 2025/8/6 11:45
 */
@Component
@Slf4j
public class FileFormatAsync {

    @Autowired
    private FileFormatConversionMapper fileFormatConversionMapper;
    @Autowired
    private TextFileUtil textFileUtil;
    @Autowired
    private MinioStorage minioStorage;

    @Autowired
    private ImageFileUtil imageFileUtil;


    /**
     * 异步转换文件
     */
    @Async("fileFormatThreadPool")
    public void fileFormatThreadPoolAsync(byte[] fileBytes,
                                          String originalFilename,
                                          String contentType,
                                          FileFormatConversion fileFormatConversion,
                                          FileFormatPathEnum fileFormatPathEnum) {
        // 1. 将byte[]转回MultipartFile
        MultipartFile multipartFile = new MockMultipartFile(
                "file",          // 表单字段名
                originalFilename, // 原始文件名
                contentType,      // 文件类型（如application/pdf）
                fileBytes         // 文件字节数组
        );
        Msg<MultipartFile> result = null;
        // 执行文件格式转换
        switch (fileFormatPathEnum.getAction()) {
            case "TEXT_TO_DOCX":
                result = textFileUtil.txtToDocx(multipartFile);
                break;
            case "TEXT_TO_PDF":
                result = textFileUtil.txtToPdf(multipartFile);
                break;
            case "PDF_TO_OFD":
                result = OfdPdfUtil.pdfToOfd(multipartFile);
                break;
            case "OFD_TO_PDF":
                result = OfdPdfUtil.ofdToPdf(multipartFile);
                break;
            case "WORD_TO_PDF":
                result = AsposeUtil.convertToPdf(multipartFile);
                break;
            case "EXCEL_TO_PDF":
                result = AsposeUtil.convertToPdf(multipartFile);
                break;
            case "JPG_TO_PNG":
                result = imageFileUtil.imageToImage(multipartFile, "png");
                break;
            case "JPG_TO_BMP":
                result = imageFileUtil.imageToImage(multipartFile, "bmp");
                break;
            case "JPG_TO_GIF":
                result = imageFileUtil.imageToImage(multipartFile, "gif");
                break;
            case "JPG_TO_PDF":
                result = imageFileUtil.imageToPdf(multipartFile);
                break;
            case "PNG_TO_JPG":
                result = imageFileUtil.imageToImage(multipartFile, "jpg");
                break;
            case "PNG_TO_BMP":
                result = imageFileUtil.imageToImage(multipartFile, "bmp");
                break;
            case "PNG_TO_GIF":
                result = imageFileUtil.imageToImage(multipartFile, "gif");
                break;
            case "PNG_TO_PDF":
                result = imageFileUtil.imageToPdf(multipartFile);
                break;
            case "GIF_TO_JPG":
                result = imageFileUtil.imageToImage(multipartFile, "jpg");
                break;
            case "GIF_TO_BMP":
                result = imageFileUtil.imageToImage(multipartFile, "bmp");
                break;
            case "GIF_TO_PNG":
                result = imageFileUtil.imageToImage(multipartFile, "png");
                break;
            case "GIF_TO_PDF":
                result = imageFileUtil.imageToPdf(multipartFile);
                break;
            case "BMP_TO_JPG":
                result = imageFileUtil.imageToImage(multipartFile, "jpg");
                break;
            case "BMP_TO_GIF":
                result = imageFileUtil.imageToImage(multipartFile, "gif");
                break;
            case "BMP_TO_PNG":
                result = imageFileUtil.imageToImage(multipartFile, "png");
                break;
            case "BMP_TO_PDF":
                result = imageFileUtil.imageToPdf(multipartFile);
                break;
            case "MP4_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "MP4_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "MP4_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "MP4_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "MP4_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "MP4_TO_WEBM":
                result = VideoConvertUtil.convertVideo(multipartFile, "webm");
                break;
            case "MP4_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "MP4_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "FLV_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "FLV_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "FLV_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "FLV_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "FLV_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "FLV_TO_WEBM":
                result = VideoConvertUtil.convertVideo(multipartFile, "webm");
                break;
            case "FLV_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "FLV_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "AVI_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "AVI_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "AVI_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "AVI_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "AVI_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "AVI_TO_WEBM":
                result = VideoConvertUtil.convertVideo(multipartFile, "webm");
                break;
            case "AVI_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "AVI_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "MOV_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "MOV_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "MOV_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "MOV_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "MOV_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "MOV_TO_WEBM":
                result = VideoConvertUtil.convertVideo(multipartFile, "webm");
                break;
            case "MOV_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "MOV_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "MKV_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "MKV_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "MKV_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "MKV_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "MKV_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "MKV_TO_WEBM":
                result = VideoConvertUtil.convertVideo(multipartFile, "webm");
                break;
            case "MKV_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "MKV_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "WMV_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "WMV_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "WMV_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "WMV_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "WMV_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "WMV_TO_WEBM":
                result = VideoConvertUtil.convertVideo(multipartFile, "webm");
                break;
            case "WMV_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "WMV_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "WEBM_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "WEBM_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "WEBM_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "WEBM_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "WEBM_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "WEBM_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "WEBM_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            case "WEBM_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "VIDEO_3GP_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "VIDEO_3GP_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "VIDEO_3GP_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "VIDEO_3GP_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "VIDEO_3GP_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "VIDEO_3GP_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "VIDEO_3GP_TO_WEBP":
                result = VideoConvertUtil.convertVideo(multipartFile, "webp");
                break;
            case "VIDEO_3GP_TO_MPEG_2":
                result = VideoConvertUtil.convertVideo(multipartFile, "mpg");
                break;
            case "MPEG2_TO_MP4":
                result = VideoConvertUtil.convertVideo(multipartFile, "mp4");
                break;
            case "MPEG2_TO_FLV":
                result = VideoConvertUtil.convertVideo(multipartFile, "flv");
                break;
            case "MPEG2_TO_AVI":
                result = VideoConvertUtil.convertVideo(multipartFile, "avi");
                break;
            case "MPEG2_TO_MOV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mov");
                break;
            case "MPEG2_TO_MKV":
                result = VideoConvertUtil.convertVideo(multipartFile, "mkv");
                break;
            case "MPEG2_TO_WMV":
                result = VideoConvertUtil.convertVideo(multipartFile, "wmv");
                break;
            case "MPEG2_TO_WEBP":
                result = VideoConvertUtil.convertVideo(multipartFile, "webp");
                break;
            case "MPEG2_TO_3GP":
                result = VideoConvertUtil.convertVideo(multipartFile, "3gp");
                break;
            default:
                result = Msg.fail("转换动作不支持!");
                break;
        }
        if (result.isSuccess()) {
            MultipartFile afterMultipartFile = result.getObj();
            String fileName = afterMultipartFile.getOriginalFilename();
            String fileSuffix = FileFormatUtil.getFileSuffix(fileName);
            String afterFilePath = fileFormatPathEnum.getPath() + "/after/" + SysUtil.getUUID() + "." + FileUtil.extName(fileName);
            // 上传文件
            minioStorage.uploadFile(afterMultipartFile, afterFilePath, fileFormatConversion.getBusinessId());
            // 获取文件大小并转换为合适单位
            long fileSizeBytes = afterMultipartFile.getSize();
            String fileSizeInfo = FileFormatUtil.formatFileSize(fileSizeBytes);
            fileFormatConversion.setAfterFileName(fileName);
            fileFormatConversion.setAfterFileFormat(fileSuffix);
            fileFormatConversion.setAfterFileSize(fileSizeInfo);
            fileFormatConversion.setAfterFileUrl(afterFilePath);
            fileFormatConversion.setConversionState(2);
            fileFormatConversion.setEndTime(new Date());
        } else {
            fileFormatConversion.setConversionState(3);
            fileFormatConversion.setEndTime(new Date());
            fileFormatConversion.setFailCause(result.getMsg());
        }
        fileFormatConversionMapper.updateById(fileFormatConversion);
    }
}
